package com.cskaoyan.javase.object.clone7.deep2;

/**
 * @description: 深度克隆
 * @author: wuguidong@cskaoyan.onaliyun.com
 **/

/**
 * 浅拷贝后的对象当中引用类型变量指向的对象是共享的
 * 所以用拷贝后的引用去修改该共享对象的成员变量
 * 原先的对象也会跟着发生变化
 *
 * 浅克隆不是真正意义上的克隆,因为它们两个对象不是完全独立,它们有共享的成员变量对象
 * 所以我们需要进行深度克隆
 *
 * 深度克隆:
 * 1,深度克隆是要在浅克隆的基础上进行的
 * 2,把B对象也拷贝一份
 * 3,然后断开拷贝中B对象引用拷贝指向B对象的引用
 * 4,然后让它指向B对象的拷贝
 *
 */
public class Demo {
    public static void main(String[] args) throws CloneNotSupportedException {
        //创建A的对象
        A a = new A(10,new B(10));
        //实现A的克隆
        //1,重写clone方法
        //2.实现接口
        Object clone = a.clone();
        //强转
        A cloneA = (A) clone;
        cloneA.b.b = 100;
        System.out.println("修改后拷贝的a对象中b对象的b的取值:"+ cloneA.b.b);
        System.out.println("修改后原先a对象中b对象的b的取值:"+ a.b.b);

        System.out.println(a.b);
        System.out.println(cloneA.b);

    }
}
class A implements Cloneable{
    int a;
    B b;
    public A() {
    }
    public A(int a, B b) {
        this.a = a;
        this.b = b;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        //1,深克隆是在浅克隆基础上进行的
        Object clone1 = super.clone();
        //2,要把B对象也拷贝一份,调用B类的clone()方法
        //需要三步走
        //这个B对象已经有了,不需要你再创建B对象了
        //这个B对象在被克隆对象的成员变量里
        //所以需要对clone做强转成A
       /* 1,用拷贝中的B对象引用做B对象的拷贝
       A cloneA = (A) clone1;
        B b = cloneA.b; //拷贝中的B对象的引用
        Object clone2 = b.clone();*/

       /*
       2,用自身对象的B对象引用做B对象的拷贝
        */
        Object clone2 = this.b.clone();
        //直接强转clone2
        B cloneB = (B) clone2;

        //现在B对象的拷贝已经有了,需要把A对象拷贝中B对象的引用指向B对象的拷贝 完成深度克隆
        A cloneA = (A) clone1;
        cloneA.b = cloneB;
        return cloneA;
    }
}
class B implements Cloneable{
    int b;
    C c;

    //需要重写B的clone方法,然后对C做克隆
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public B() {
    }

    public B(int b) {
        this.b = b;
    }
}
class C{
    int c;
}
